#include "../include/aj_session_threads.h"

NETAPI::SessionThreads::SessionThreads()
{

}

NETAPI::SessionThreads::~SessionThreads()
{
    Stop();
}

bool NETAPI::SessionThreads::Start(uint threadNum)
{
    if (m_isRunning)
    {
        return true;
    }
    for (uint i = 0; i < threadNum; ++i)
    {
        TcpThread *thread = new TcpThread();
        m_threadList.push_back(thread);
        thread->start();
    }
    m_isRunning = true;
    return true;
}

void NETAPI::SessionThreads::Stop()
{
    if (!m_isRunning)
    {
        return;
    }
    //先关已有连接
    {
        std::lock_guard<std::mutex> locker(m_lock);
        std::unordered_map<void*, std::shared_ptr<TcpSession>>::iterator itor = m_sessionList.begin();
        //关闭连接
        for (itor = m_sessionList.begin(); itor != m_sessionList.end(); ++itor)
        {
            std::shared_ptr<TcpSession> session = itor->second;
            if (session.get())
            {
                disconnect(session.get(),&TcpSession::SignalDisConnected,this,&SessionThreads::SlotSessionDisConnected);
                session.get()->Disconnect();
            }
        }
    }
    for (TcpThread *thread : m_threadList)
    {
        thread->exit();
        thread->wait();
    }
    for (TcpThread *thread : m_threadList)
    {
        delete thread;
    }
    m_threadList.clear();
    m_sessionList.clear();
    m_isRunning = false;
}

NETAPI::TcpThread *NETAPI::SessionThreads::PickMinThread()
{
    TcpThread *thread = nullptr;
    uint32_t mincount = 65535;
    for (TcpThread *tmpthread : m_threadList)
    {
        uint32_t tmpcount = tmpthread->m_sessionCount;
        if (tmpcount < mincount)
        {
            mincount = tmpcount;
            thread = tmpthread;
        }
    }
    return thread;
}

std::vector<uint32_t> NETAPI::SessionThreads::GetSessionSize() const
{
    std::vector<uint32_t> vec;
    for (TcpThread *thread : m_threadList)
        vec.push_back(thread->m_sessionCount);
    return vec;
}

void NETAPI::SessionThreads::AddSession(std::shared_ptr<NETAPI::TcpSession> &session)
{
    connect(session.get(),
        &TcpSession::SignalDisConnected,
        this,
        &SessionThreads::SlotSessionDisConnected,
        Qt::QueuedConnection);
    //加锁
    std::lock_guard<std::mutex> locker(m_lock);
    m_sessionList[session.get()] = session;
}

//会话断开
void NETAPI::SessionThreads::SlotSessionDisConnected(void *id)
{
    //加锁
    std::lock_guard<std::mutex> locker(m_lock);
    std::unordered_map<void*, std::shared_ptr<TcpSession>>::iterator itor = m_sessionList.begin();
    itor = m_sessionList.find(id);
    if (itor != m_sessionList.end())
    {
        m_sessionList.erase(itor);
    }
}
